home *** CD-ROM | disk | FTP | other *** search
- /*
- ** TimeDate.c
- **
- ** Phone rate calculation support routines
- **
- ** Copyright © 1990-1996 by Olaf `Olsen' Barthel
- ** All Rights Reserved
- **
- ** :ts=4
- */
-
- #ifndef _GLOBAL_H
- #include "Global.h"
- #endif
-
- /* SelectTime():
- *
- * Searches for the correct unit/pay conversion values.
- */
-
- VOID
- SelectTime(struct PhoneEntry *SomeEntry,struct List *List,struct timeval *TimeVal)
- {
- struct TimeDateNode *TimeDateNode;
- struct ClockData ClockData;
- LONG Time;
- BOOL FoundOne = FALSE;
- LONG i,Last;
-
- /* If we get a specific time of day, use it. */
-
- if(TimeVal)
- Amiga2Date(TimeVal->tv_secs,&ClockData);
- else
- {
- struct timeval Now;
-
- /* Obtain current time and date. */
-
- GetSysTime(&Now);
-
- /* Convert into a more suitable form (note: seconds are
- * required as an input value, ice is extra).
- */
-
- Amiga2Date(Now.tv_secs,&ClockData);
- }
-
- /* Apparently, in the US of A the week starts with Sunday, we'll
- * wrap the week around to let it start with Monday.
- */
-
- if(ClockData . wday)
- ClockData . wday--;
- else
- ClockData . wday = 6;
-
- /* Change the month, too... */
-
- ClockData . month--;
-
- if(List)
- {
- if(!List->lh_Head->ln_Succ)
- List = NULL;
- }
-
- /* If no special list to search is given use the phonebook entry. */
-
- if(!List)
- {
- if(SomeEntry && !SomeEntry->Header->NoRates)
- List = (struct List *)&SomeEntry->TimeDateList;
- else
- {
- PayPerUnit[DT_FIRST_UNIT] = 0;
- PayPerUnit[DT_NEXT_UNIT] = 0;
- SecPerUnit[DT_FIRST_UNIT] = 0;
- SecPerUnit[DT_NEXT_UNIT] = 0;
-
- return;
- }
- }
-
- if(!List->lh_Head->ln_Succ)
- {
- PayPerUnit[DT_FIRST_UNIT] = 0;
- PayPerUnit[DT_NEXT_UNIT] = 0;
- SecPerUnit[DT_FIRST_UNIT] = 0;
- SecPerUnit[DT_NEXT_UNIT] = 0;
-
- return;
- }
-
- /* First step: search for current day. */
-
- TimeDateNode = (struct TimeDateNode *)List->lh_Head;
-
- /* Skip first entry. */
-
- TimeDateNode = (struct TimeDateNode *)TimeDateNode->VanillaNode . ln_Succ;
-
- /* First step: search for date settings. */
-
- while(TimeDateNode->VanillaNode . ln_Succ)
- {
- /* Does it match a specific date? */
-
- if(TimeDateNode->Header . Month == ClockData . month && TimeDateNode->Header . Day == ClockData . mday)
- {
- FoundOne = TRUE;
-
- break;
- }
-
- TimeDateNode = (struct TimeDateNode *)TimeDateNode->VanillaNode . ln_Succ;
- }
-
- /* Second step: search for week day settings. */
-
- if(!FoundOne)
- {
- TimeDateNode = (struct TimeDateNode *)List->lh_Head;
-
- /* Skip first entry. */
-
- TimeDateNode = (struct TimeDateNode *)TimeDateNode->VanillaNode . ln_Succ;
-
- while(TimeDateNode->VanillaNode . ln_Succ)
- {
- /* Does it match a specific day? */
-
- if(TimeDateNode->Header . Month == -1 && (TimeDateNode->Header . Day & (1L << ClockData . wday)))
- {
- FoundOne = TRUE;
-
- break;
- }
-
- TimeDateNode = (struct TimeDateNode *)TimeDateNode->VanillaNode . ln_Succ;
- }
- }
-
- /* Third step: use default settings. */
-
- if(!FoundOne)
- TimeDateNode = (struct TimeDateNode *)List->lh_Head;
-
- /* Convert current time to packed format. */
-
- Time = DT_GET_TIME(ClockData . hour,ClockData . min);
-
- /* Start with a blank. */
-
- Last = -1;
-
- /* Look for fitting time. */
-
- for(i = 0 ; i < TimeDateNode->Table[0] . Count ; i++)
- {
- /* The time we are looking for must be >= the
- * current time.
- */
-
- if(TimeDateNode->Table[i] . Time > Time)
- {
- if(i == 0)
- break;
- else
- {
- Last = i - 1;
- break;
- }
- }
- else
- continue;
- }
-
- /* If none is found, take the last one in the list.
- * Note that this requires the list to be sorted in
- * ascending order.
- */
-
- if(Last == -1)
- Last = TimeDateNode->Table[0] . Count - 1;
-
- /* Fill in the remaining data. */
-
- PayPerUnit[DT_FIRST_UNIT] = TimeDateNode->Table[Last] . PayPerUnit[DT_FIRST_UNIT];
- PayPerUnit[DT_NEXT_UNIT] = TimeDateNode->Table[Last] . PayPerUnit[DT_NEXT_UNIT];
- SecPerUnit[DT_FIRST_UNIT] = TimeDateNode->Table[Last] . SecPerUnit[DT_FIRST_UNIT];
- SecPerUnit[DT_NEXT_UNIT] = TimeDateNode->Table[Last] . SecPerUnit[DT_NEXT_UNIT];
- }
-
- struct List *
- FindTimeDate(struct List *Patterns,STRPTR Number)
- {
- struct PatternNode *Node;
- UBYTE Dst[516];
-
- if(Kick30)
- {
- for(Node = (struct PatternNode *)Patterns->lh_Head ; Node->Node . ln_Succ ; Node = (struct PatternNode *)Node->Node . ln_Succ)
- {
- if(ParsePatternNoCase(Node->Pattern,Dst,516) != -1)
- {
- if(MatchPatternNoCase(Dst,Number))
- return(&Node->List);
- }
- }
- }
- else
- {
- UBYTE Src[256];
- STRPTR Index;
-
- for(Node = (struct PatternNode *)Patterns->lh_Head ; Node->Node . ln_Succ ; Node = (struct PatternNode *)Node->Node . ln_Succ)
- {
- strcpy(Index = Src,Node->Pattern);
-
- while(*Index)
- {
- *Index = ToUpper(*Index);
-
- Index++;
- }
-
- if(ParsePatternNoCase(Src,Dst,516) != -1)
- {
- if(MatchPatternNoCase(Dst,Number))
- return(&Node->List);
- }
- }
- }
-
- return(NULL);
- }
-
- VOID
- DeletePatternNode(struct PatternNode *Pattern)
- {
- if(Pattern)
- {
- struct TimeDateNode *Node,
- *NextNode;
-
- for(Node = (struct TimeDateNode *)Pattern->List . lh_Head ; NextNode = (struct TimeDateNode *)Node->VanillaNode . ln_Succ ; Node = NextNode)
- FreeTimeDateNode(Node);
-
- FreeVecPooled(Pattern);
- }
- }
-
- struct PatternNode *
- CreatePatternNode(STRPTR Comment)
- {
- struct PatternNode *Node;
-
- if(Node = (struct PatternNode *)AllocVecPooled(sizeof(struct PatternNode),MEMF_ANY | MEMF_CLEAR))
- {
- struct TimeDateNode *TimeDateNode;
-
- Node->Node . ln_Name = Node->Comment;
-
- strcpy(Node->Comment,Comment);
-
- NewList(&Node->List);
-
- if(TimeDateNode = CreateTimeDateNode(-1,-1,"",2))
- {
- AddTail(&Node->List,&TimeDateNode->VanillaNode);
-
- return(Node);
- }
-
- FreeVecPooled(Node);
- }
-
- return(NULL);
- }
-
- VOID
- DeletePatternList(struct List *List)
- {
- if(List)
- {
- FreePatternList(List);
-
- FreeVecPooled(List);
- }
- }
-
- VOID
- FreePatternList(struct List *List)
- {
- if(List)
- {
- struct PatternNode *Pattern,
- *NextPattern;
-
- for(Pattern = (struct PatternNode *)List->lh_Head ; NextPattern = (struct PatternNode *)Pattern->Node . ln_Succ ; Pattern = NextPattern)
- DeletePatternNode(Pattern);
-
- NewList(List);
- }
- }
-
- VOID
- ConvertTimeDate(struct TimeDateOld *Old,struct TimeDate *New)
- {
- memset(New,0,sizeof(struct TimeDate));
-
- New->Count = Old->Count;
- New->PayPerUnit[0] = ((ULONG)Old->PayPerUnit[0]) * 10000;
- New->PayPerUnit[1] = ((ULONG)Old->PayPerUnit[1]) * 10000;
- New->SecPerUnit[0] = ((ULONG)Old->SecPerUnit[0]) * 10000;
- New->SecPerUnit[1] = ((ULONG)Old->SecPerUnit[1]) * 10000;
- New->Time = Old->Time;
- New->Mark = FALSE;
- }
-
- struct List *
- LoadTimeDateList(STRPTR Name,LONG *Error)
- {
- struct IFFHandle *Handle;
- struct List *List = NULL;
-
- *Error = 0;
-
- if(Handle = (struct IFFHandle *)AllocIFF())
- {
- if(Handle->iff_Stream = Open(Name,MODE_OLDFILE))
- {
- InitIFFasDOS(Handle);
-
- if(!(*Error = OpenIFF(Handle,IFFF_READ)))
- {
- STATIC LONG Stops[4 * 2] =
- {
- ID_TERM, ID_VERS,
- ID_TERM, ID_NAME,
- ID_TERM, ID_DAT2,
- ID_TERM, ID_DATE
- };
-
- struct ContextNode *Chunk;
-
- if(!(*Error = StopChunks(Handle,Stops,4)))
- {
- if(List = (struct List *)AllocVecPooled(sizeof(struct MinList),MEMF_ANY))
- {
- struct PatternNode *Pattern = NULL;
-
- NewList(List);
-
- while(!ParseIFF(Handle,IFFPARSE_SCAN))
- {
- Chunk = CurrentChunk(Handle);
-
- if(Chunk->cn_ID == ID_NAME)
- {
- if(Pattern = (struct PatternNode *)AllocVecPooled(sizeof(struct PatternNode),MEMF_ANY | MEMF_CLEAR))
- {
- if(ReadChunkBytes(Handle,Pattern->Pattern,Chunk->cn_Size) == Chunk->cn_Size)
- {
- NewList(&Pattern->List);
-
- Pattern->Node . ln_Name = Pattern->Comment;
-
- AddTail(List,Pattern);
- }
- else
- {
- *Error = IoErr();
-
- FreeVecPooled(Pattern);
-
- break;
- }
- }
- else
- {
- *Error = ERR_NO_MEM;
-
- break;
- }
- }
-
- if(Chunk->cn_ID == ID_DATE)
- {
- struct TimeDateNode *Node;
- LONG Count = (Chunk->cn_Size - sizeof(struct TimeDateHeader)) / sizeof(struct TimeDateOld);
-
- if(!Pattern)
- {
- *Error = IFFERR_MANGLED;
-
- break;
- }
-
- if(Node = CreateTimeDateNode(-1,-1,"",Count))
- {
- struct TimeDateOld *Old;
-
- if(Old = (struct TimeDateOld *)AllocVecPooled(sizeof(struct TimeDateOld) * Count,MEMF_ANY))
- {
- if(ReadChunkBytes(Handle,&Node->Header,sizeof(struct TimeDateHeader)) == sizeof(struct TimeDateHeader))
- {
- if(ReadChunkRecords(Handle,Old,sizeof(struct TimeDateOld),Count) == Count)
- {
- LONG i;
-
- for(i = 0 ; i < Count ; i++)
- ConvertTimeDate(&Old[i],&Node->Table[i]);
-
- AdaptTimeDateNode(Node);
-
- AddTail(&Pattern->List,&Node->VanillaNode);
-
- FreeVecPooled(Old);
- }
- else
- {
- *Error = IoErr();
-
- FreeTimeDateNode(Node);
- FreeVecPooled(Old);
-
- break;
- }
- }
- else
- {
- *Error = IoErr();
-
- FreeTimeDateNode(Node);
- FreeVecPooled(Old);
-
- break;
- }
- }
- }
- else
- {
- *Error = ERROR_NO_FREE_STORE;
- break;
- }
- }
-
- if(Chunk->cn_ID == ID_DAT2)
- {
- struct TimeDateNode *Node;
- LONG Count = (Chunk->cn_Size - sizeof(struct TimeDateHeader)) / sizeof(struct TimeDate);
-
- if(!Pattern)
- {
- *Error = IFFERR_MANGLED;
-
- break;
- }
-
- if(Node = CreateTimeDateNode(-1,-1,"",Count))
- {
- if(ReadChunkBytes(Handle,&Node->Header,sizeof(struct TimeDateHeader)) == sizeof(struct TimeDateHeader))
- {
- if(ReadChunkRecords(Handle,Node->Table,sizeof(struct TimeDate),Count) == Count)
- {
- AdaptTimeDateNode(Node);
-
- AddTail(&Pattern->List,&Node->VanillaNode);
- }
- else
- {
- *Error = IoErr();
-
- FreeTimeDateNode(Node);
-
- break;
- }
- }
- else
- {
- *Error = IoErr();
-
- FreeTimeDateNode(Node);
-
- break;
- }
- }
- else
- {
- *Error = ERROR_NO_FREE_STORE;
- break;
- }
- }
- }
- }
- }
-
- CloseIFF(Handle);
- }
-
- Close(Handle->iff_Stream);
- }
- else
- *Error = IoErr();
-
- FreeIFF(Handle);
- }
- else
- *Error = ERR_NO_MEM;
-
- if(*Error)
- {
- DeletePatternList(List);
-
- return(NULL);
- }
- else
- return(List);
- }
-
- BOOL
- SaveTimeDateList(STRPTR Name,struct List *List,LONG *Error)
- {
- *Error = 0;
-
- #ifdef BETA
- if(ShowRequest(Window,
- "ONE WAY TICKET WARNING!\n\n"
- "The file format written by this `term' beta test release\n"
- "cannot be read by older program releases. And just as it\n"
- "happens, not even the author of these lines can guarantee\n"
- "you that this very program will be able to read the files\n"
- "back it writes.",
- "Uh oh...|I know what I'm doing"))
- return(TRUE);
- #endif
-
- if(List->lh_Head->ln_Succ)
- {
- struct IFFHandle *Handle;
-
- if(Handle = (struct IFFHandle *)AllocIFF())
- {
- BOOL Created;
-
- if(Handle->iff_Stream = Open(Name,MODE_NEWFILE))
- {
- Created = TRUE;
-
- InitIFFasDOS(Handle);
-
- if(!(*Error = OpenIFF(Handle,IFFF_WRITE)))
- {
- if(!(*Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
- {
- if(!(*Error = PushChunk(Handle,0,ID_VERS,IFFSIZE_UNKNOWN)))
- {
- struct TermInfo TermInfo;
-
- TermInfo . Version = CONFIG_FILE_VERSION;
- TermInfo . Revision = CONFIG_FILE_REVISION;
-
- if(WriteChunkRecords(Handle,&TermInfo,sizeof(struct TermInfo),1) == 1)
- {
- if(!(*Error = PopChunk(Handle)))
- {
- struct PatternNode *Node;
-
- for(Node = (struct PatternNode *)List->lh_Head ; !(*Error) && Node->Node . ln_Succ ; Node = (struct PatternNode *)Node->Node . ln_Succ)
- {
- if(!(*Error = PushChunk(Handle,0,ID_NAME,296)))
- {
- if(WriteChunkBytes(Handle,Node->Pattern,296) == 296)
- {
- if(!(*Error = PopChunk(Handle)))
- {
- struct TimeDateNode *TimeDateNode;
-
- for(TimeDateNode = (struct TimeDateNode *)Node->List . lh_Head ; TimeDateNode->VanillaNode . ln_Succ ; TimeDateNode = (struct TimeDateNode *)TimeDateNode->VanillaNode . ln_Succ)
- {
- if(!(*Error = PushChunk(Handle,0,ID_DAT2,sizeof(struct TimeDateHeader) + TimeDateNode->Table[0] . Count * sizeof(struct TimeDate))))
- {
- if(WriteChunkBytes(Handle,&TimeDateNode->Header,sizeof(struct TimeDateHeader)) != sizeof(struct TimeDateHeader))
- {
- *Error = IoErr();
-
- break;
- }
- else
- {
- if(WriteChunkBytes(Handle,TimeDateNode->Table,TimeDateNode->Table[0] . Count * sizeof(struct TimeDate)) != TimeDateNode->Table[0] . Count * sizeof(struct TimeDate))
- {
- *Error = IoErr();
-
- break;
- }
- else
- {
- if(*Error = PopChunk(Handle))
- break;
- }
- }
- }
- else
- break;
- }
- }
- }
- else
- *Error = IoErr();
- }
- }
- }
- }
- }
-
- if(!(*Error))
- *Error = PopChunk(Handle);
- }
-
- CloseIFF(Handle);
- }
-
- Close(Handle->iff_Stream);
- }
- else
- {
- *Error = IoErr();
-
- Created = FALSE;
- }
-
- if(Created)
- {
- if(*Error)
- DeleteFile(Name);
- else
- AddProtection(Name,FIBF_EXECUTE);
- }
-
- FreeIFF(Handle);
- }
- else
- *Error = ERR_NO_MEM;
- }
-
- if(*Error)
- return(FALSE);
- else
- return(TRUE);
- }
-